<script setup>
import { onMounted, onUnmounted, ref, watch } from 'vue'
import {
  getStuLogAPI,
  updateStuDataAPI,
  updatePasswordAPI,
  addClassAPI,
  updateStuPhoneAPI
} from '@/api/user.js'
import { useStuStore } from '@/stores/'
import { useRouter } from 'vue-router'
import { formatDate } from '@/utils/format.js'
import { checkPhone } from '@/utils/utils.js'
import UploadImage from './components/UploadImage.vue'
import { Plus } from '@element-plus/icons-vue'
import { debounce } from 'lodash'
import { ElMessage } from 'element-plus'
import { getCodeAPI } from '@/api/login'
import { checkQRCodeAPI, getQRCodeAPI } from '@/api/login'
import { socket } from '@/utils/socket'

const stuStore = useStuStore()
const router = useRouter()
// tab栏
const activeName = ref('userLog')

// 用户动态
const stuLogParams = ref({
  id: stuStore.stuInfo?.id,
  pageIndex: 1,
  pageSize: 10
})
const stuLogList = ref([])
const isOver = ref(false)
const getStuLogList = async () => {
  if (isOver.value) {
    return
  }
  const { data: res } = await getStuLogAPI(stuLogParams.value)
  if (res.status === 200) {
    if (res.data.length < stuLogParams.value.pageSize) {
      isOver.value = true
    }
    stuLogList.value = [...stuLogList.value, ...res.data]
  }
}
getStuLogList()
const scrollRef = ref()
const scrollTop = ref(0) // 记录数据加载前滚动条的位置，用来手动定位scrollbar
const handleScroll = debounce((e) => {
  const wrapRef = scrollRef.value.wrapRef
  scrollRef.value.moveY = (wrapRef.scrollTop * 100) / wrapRef.clientHeight
  const poor = wrapRef.scrollHeight - wrapRef.clientHeight
  if (e.scrollTop + 2 > poor) {
    scrollTop.value = e.scrollTop
    stuLogParams.value.pageIndex += 1
  }
}, 100)

watch(
  () => stuLogParams.value.pageIndex,
  () => {
    if (stuLogParams.value.pageIndex > 1 && !isOver.value) {
      getStuLogList()
    }
  }
)

// 修改资料
stuStore.getStudent()
const stuDataForm = ref()
const stuData = ref({
  id: stuStore.stuInfo.id,
  realName: stuStore.stuInfo.realName || '',
  age: stuStore.stuInfo.age || '',
  gender: stuStore.stuInfo.gender || '',
  birthDay: stuStore.stuInfo.birthDay || ''
})
const stuDataRules = {
  realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  age: [],
  gender: [],
  birthDay: [],
  phone: [
    {
      validator: checkPhone,
      trigger: 'change'
    }
  ]
}
// 提交资料
const updateData = async () => {
  const r = await stuDataForm.value.validate()
  if (r) {
    const { data: res } = await updateStuDataAPI(stuData.value)
    if (res.status === 200) {
      ElMessage.success('修改成功')
      stuStore.getStudent()
      getStuLogList()
    }
  }
}

// 修改密码
const stuPwdForm = ref()
const stuPassword = ref({
  oldPassword: '',
  newPassword: '',
  confirmPwd: ''
})
const checkPwd = (rule, value, callback) => {
  if (value === stuPassword.value.newPassword) {
    callback()
  } else {
    callback(new Error('新旧密码不一致'))
  }
}
const stuPwdRules = {
  oldPassword: [{ required: true, message: '请输入旧密码' }],
  newPassword: [{ required: true, message: '请输入新密码' }],
  confirmPwd: [
    { required: true, message: '请确认密码' },
    { validator: checkPwd, trigger: 'blur' }
  ]
}

const updatePwd = async () => {
  const r = await stuPwdForm.value.validate()
  if (!r) {
    return
  }
  const { data: res } = await updatePasswordAPI(stuPassword.value)
  if (res.status === 200) {
    ElMessage.success(res.message)
    localStorage.removeItem('uid')
    localStorage.removeItem('u')
    localStorage.removeItem('t')
    router.push('/login')
  } else {
    ElMessage.error(res.message)
  }
  stuPwdForm.value.resetFields()
}

// 修改手机
const stuPhone = ref({
  id: stuStore.stuInfo.id,
  phone: stuStore.stuInfo.phone || '',
  code: ''
})
const stuPhoneRule = {
  phone: [
    {
      required: true,
      message: '请输入手机号',
      trigger: 'blur'
    },
    {
      validator: checkPhone,
      trigger: 'change'
    }
  ],
  code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
}
const stuPhoneRef = ref()
const updatePhone = async () => {
  const r = await stuPhoneRef.value.validate()
  if (!r) {
    return
  }
  const { data: res } = await updateStuPhoneAPI(stuPhone.value)
  if (res.status === 200) {
    return ElMessage.success(res.message)
  }
  return ElMessage.error(res.message)
}
// 获取验证码
let n = null
const time = ref(60)
const isDisabled = ref(false)
const getCode = async () => {
  const r = await stuPhoneRef.value.validateField(['phone'])
  if (!r) {
    return
  }
  const { data: res } = await getCodeAPI(stuPhone.value.phone)
  if (res.status === 200) {
    ElMessage.success(res.message)
    isDisabled.value = true
    n = setInterval(() => {
      time.value--
      if (time.value === 0) {
        isDisabled.value = false
        time.value = 60
        clearInterval(n)
      }
    }, 1000)
  } else {
    ElMessage.error(res.message)
  }
}
onUnmounted(() => {
  clearInterval(n)
})

// 添加班级
const classDialogVisible = ref(false)
const classNode = ref('')
const openDialog = () => {
  classDialogVisible.value = true
}
const addClass = async () => {
  const { data: res } = await addClassAPI(classNode.value)
  if (res.status === 200) {
    classDialogVisible.value = false
    ElMessage.success(res.message)
    stuStore.getStudent()
  } else {
    ElMessage.error(res.message)
  }
}

// 绑定微信
const bindWxDialog = ref(false)
const wxQRCode = ref('')
const timeout = ref(null)
const scene = ref('')
const wxQRCodeStatus = ref(false)
const getQRCode = async () => {
  clearInterval(timeout.value)
  const { data: res } = await getQRCodeAPI({
    status: true,
    userId: stuStore.stuInfo.id
  })
  if (res.status === 200) {
    wxQRCode.value = res.data
    scene.value = res.scene
    socket.emit('loginQRCodeStatus', scene.value)

    timeout.value = setInterval(async () => {
      const { data: checkRes } = await checkQRCodeAPI(res.scene)
      if (checkRes.status === 200) {
        wxQRCodeStatus.value = true
        clearInterval(timeout.value)
      }
      if (checkRes.status === 400) {
        wxQRCode.value = ''
        clearInterval(timeout.value)
      }
    }, 3000)
  }
}
const openBindWxDialog = () => {
  bindWxDialog.value = true
  getQRCode()
}
const closeBindWxDialog = () => {
  clearInterval(timeout.value)
  timeout.value = null
  wxQRCode.value = ''
  scene.value = ''
  wxQRCodeStatus.value = false
  bindWxDialog.value = false
}

onMounted(() => {
  socket.off('resendLoginStatus')
  socket.on('resendLoginStatus', (data) => {
    if (data.status === 200) {
      ElMessage.success(data.message)
      closeBindWxDialog()
      stuStore.getStudent()
    }
  })
})
</script>

<template>
  <div class="user-container">
    <div class="user-card">
      <el-card body-class="user-card-body" shadow="hover" header="个人信息">
        <div class="user-card-body-box">
          <UploadImage>
            <el-avatar
              class="user-card-avatar"
              :src="stuStore.stuInfo?.imagePath"
              v-if="stuStore.stuInfo?.imagePath"
            />
            <el-icon v-else class="user-card-avatar-icon">
              <Plus />
            </el-icon>
          </UploadImage>
          <span class="user-card-name">
            {{ stuStore.stuInfo?.user_name }}
          </span>
        </div>
        <ul>
          <li class="item">姓名：{{ stuStore.stuInfo?.realName }}</li>
          <li class="item">年龄：{{ stuStore.stuInfo?.age }}</li>
          <li class="item">
            性别：{{ stuStore.stuInfo?.gender ? '男' : '女' }}
          </li>
          <li class="item">
            学院：{{ stuStore.stuInfo?.collegeName || '暂无' }}
          </li>
          <li class="item">
            专业：{{ stuStore.stuInfo?.departmentName || '暂无' }}
          </li>
          <li class="item">
            班级：<el-button
              v-if="!stuStore.stuInfo?.className"
              @click="openDialog"
            >
              加入班级 </el-button
            ><span v-else>{{ stuStore.stuInfo?.className }}</span>
          </li>
          <li class="item">
            注册时间：{{
              formatDate(stuStore.stuInfo?.create_time, 'YYYY-MM-DD')
            }}
          </li>
        </ul>
        <el-button
          style="margin-top: 0.1rem"
          v-if="!stuStore.stuInfo.bindWxStatus"
          @click="openBindWxDialog"
        >
          绑定微信
        </el-button>
      </el-card>
    </div>
    <div class="user-data-card">
      <el-card shadow="hover">
        <el-tabs v-model="activeName" class="demo-tabs">
          <el-tab-pane label="用户动态" name="userLog">
            <el-scrollbar
              ref="scrollRef"
              @scroll="handleScroll"
              max-height="5rem"
              style="margin-top: 0.2rem"
            >
              <el-timeline class="user-data-card-timeline">
                <el-timeline-item
                  v-for="item in stuLogList"
                  :key="item.id"
                  placement="top"
                  size="large"
                  :timestamp="formatDate(item.create_time, 'YYYY-MM-DD')"
                >
                  <el-card>
                    <h3 class="item-content">
                      {{ item.real_name }} {{ item.content }}
                    </h3>
                    <p class="item-time">
                      {{ formatDate(item.create_time, 'YYYY-MM-DD HH:mm:ss') }}
                    </p>
                  </el-card>
                </el-timeline-item>
              </el-timeline>
            </el-scrollbar>
          </el-tab-pane>
          <el-tab-pane label="修改资料" name="updateData">
            <el-form
              ref="stuDataForm"
              label-width="1rem"
              :model="stuData"
              :rules="stuDataRules"
            >
              <el-form-item label="姓名" prop="realName">
                <el-input
                  style="width: 30%"
                  placeholder="请输入姓名"
                  v-model="stuData.realName"
                ></el-input>
              </el-form-item>
              <el-form-item label="年龄" prop="age">
                <el-input-number
                  style="width: 30%"
                  v-model="stuData.age"
                  :min="18"
                  :max="30"
                />
              </el-form-item>
              <el-form-item label="性别" prop="gender">
                <el-select
                  style="width: 30%"
                  v-model="stuData.gender"
                  placeholder="请选择性别"
                >
                  <el-option label="男" :value="1" />
                  <el-option label="女" :value="0" />
                </el-select>
              </el-form-item>
              <el-form-item label="出生日期" prop="birthDay">
                <el-date-picker
                  style="width: 30%"
                  v-model="stuData.birthDay"
                  type="date"
                  placeholder="请选择日期"
                />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="updateData">提交</el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
          <el-tab-pane label="修改密码" name="updatePassword">
            <el-form
              label-width="1rem"
              :model="stuPassword"
              :rules="stuPwdRules"
              ref="stuPwdForm"
            >
              <el-form-item label="旧密码" prop="oldPassword">
                <el-input
                  v-model="stuPassword.oldPassword"
                  show-password
                  style="width: 30%"
                  placeholder="请输入旧密码"
                  type="password"
                ></el-input>
              </el-form-item>
              <el-form-item label="新密码" prop="newPassword">
                <el-input
                  v-model="stuPassword.newPassword"
                  show-password
                  style="width: 30%"
                  placeholder="请输入新密码"
                  type="password"
                ></el-input>
              </el-form-item>
              <el-form-item label="确认密码" prop="confirmPwd">
                <el-input
                  v-model="stuPassword.confirmPwd"
                  show-password
                  style="width: 30%"
                  placeholder="请再次输入新密码"
                  type="password"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="updatePwd">提交</el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
          <el-tab-pane label="修改手机号" name="updatePhone">
            <el-form
              :model="stuPhone"
              :rules="stuPhoneRule"
              ref="stuPhoneRef"
              label-width="1rem"
            >
              <el-form-item label="手机号" prop="phone">
                <el-input
                  style="width: 30%; margin-right: 0.1rem"
                  placeholder="请输入手机号"
                  v-model="stuPhone.phone"
                  :disabled="isDisabled"
                ></el-input>
                <el-button :disabled="isDisabled" @click="getCode">
                  {{ time < 60 ? time : '获取验证码' }}
                </el-button>
              </el-form-item>
              <el-form-item label="验证码" prop="code">
                <el-input
                  style="width: 30%"
                  placeholder="请输入验证码"
                  v-model="stuPhone.code"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="updatePhone">提交</el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </div>
  </div>
  <el-dialog v-model="classDialogVisible" title="加入班级" width="20%">
    <el-form>
      <el-form-item label="班级码">
        <el-input v-model="classNode" placeholder="请输入班级码"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" style="width: 100%" @click="addClass">
          加入
        </el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
  <el-dialog
    v-model="bindWxDialog"
    title="绑定微信"
    width="20%"
    @close="closeBindWxDialog"
  >
    <div class="user-bind-wx">
      <el-image style="width: 100%; height: 100%" :src="wxQRCode" fit="fit">
        <template #error>
          <div class="image-slot" @click="getQRCode">
            <el-icon><i-ep-picture /></el-icon>
            <span>点击重新获取二维码</span>
          </div>
        </template>
      </el-image>
      <span class="user-wx-qrcode-scan" v-if="wxQRCodeStatus"> 已扫码 </span>
    </div>
  </el-dialog>
</template>

<style lang="scss" scoped>
@media screen and (max-width: 1024px) {
  .user-container {
    margin: 0.4rem 0.6rem !important;
    display: flex;
    flex-direction: column;
    .user-card {
      margin-right: 0 !important;
      margin-bottom: 0.2rem;
      .user-card-body-box {
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        align-content: center;
        margin-bottom: 0.2rem;
        .user-card-avatar {
          width: 1rem;
          height: 1rem;
        }
        .user-card-avatar-icon {
          font-size: 0.28rem;
          color: #8c939d;
          text-align: center;
        }
      }

      .user-card-name {
        display: flex;
        justify-content: center;
        font-size: 0.18rem;
        margin-top: 0.1rem;
      }

      .item {
        font-size: 0.16rem;
        color: #909399;
        padding: 0.04rem 0;
      }
    }

    .user-data-card {
      flex: 2;

      .user-data-card-timeline {
        padding-left: 0.4rem;

        .item-content {
          margin-bottom: 0.2rem;
        }

        .item-time {
          color: #909399;
        }
      }
    }
  }
}
.user-container {
  margin: 0.4rem 0.6rem;
  display: flex;
  font-size: 0.14rem;
  .user-card {
    flex: 1;
    margin-right: 0.2rem;

    .user-card-body-box {
      display: flex;
      flex-wrap: wrap;
      flex-direction: column;
      align-content: center;
      margin-bottom: 0.2rem;
      .user-card-avatar {
        width: 1rem;
        height: 1rem;
      }
      .user-card-avatar-icon {
        font-size: 0.28rem;
        color: #8c939d;
        text-align: center;
      }
    }

    .user-card-name {
      display: flex;
      justify-content: center;
      font-size: 0.18rem;
      margin-top: 0.1rem;
    }

    .item {
      font-size: 0.16rem;
      color: #909399;
      padding: 0.04rem 0;
    }
  }

  .user-data-card {
    flex: 2;

    .user-data-card-timeline {
      padding-left: 0.4rem;

      .item-content {
        margin-bottom: 0.2rem;
      }

      .item-time {
        color: #909399;
      }
    }
  }
}
.user-bind-wx {
  position: relative;
  .image-slot {
    cursor: pointer;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 3.5rem;
    height: 3.5rem;
    background: var(--el-fill-color-light);
    color: var(--el-text-color-secondary);
    font-size: 0.3rem;
    .el-icon {
      width: 0.3rem;
      height: 0.3rem;
    }
    span {
      font-size: 0.14rem;
      margin-top: 0.4rem;
    }
  }
  .user-wx-qrcode-scan {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    padding: 0.2rem;
    backdrop-filter: blur(0.03rem);
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: 600;
    font-size: 0.24rem;
    letter-spacing: 0.04rem;
  }
}
</style>
